# -*- coding: utf-8 -*-
from pygame.locals import *
import pygame


def Debug(msg, _type='Message'):
    print '     %s: %s' % (_type, msg)

##CONSTANTS##
#Directions
DIRECTION_UP = 0
DIRECTION_DOWN = 1
DIRECTION_LEFT = 2
DIRECTION_RIGHT = 3

#The lesser speed is faster. In fact, speed is actually a "sleep".  xD
RUN_SPEED = 3
WALK_SPEED = 5
VERT_SPEED = 1

#Xiao Image Size
XIAO_WIDTH = 30
XIAO_HEIGHT = 70

#Screen Size
WIDTH = 800
HEIGHT = 600

#Top limit inside de screen
TOP_LIMIT = HEIGHT*40/100

#Jump Control
MAX_JUMPS = 80
MAX_STAY_RUN = 10
MAX_STAY_WALK = 10
ACC = 3

#Start Rect Player 1
START_RECT1 = pygame.Rect(0,TOP_LIMIT+1,XIAO_WIDTH,XIAO_HEIGHT)

#Start Rect Player 2
START_RECT2 = pygame.Rect(WIDTH-XIAO_WIDTH,HEIGHT-XIAO_HEIGHT,XIAO_WIDTH,XIAO_HEIGHT)

#Player 1
P1_UP = K_w
P1_DOWN = K_s
P1_LEFT = K_a
P1_RIGHT = K_d
P1_ATK = K_h
P1_JMP = K_j
P1_BLK = K_k

#Player 2
P2_UP = K_KP8
P2_DOWN = K_KP5
P2_LEFT = K_KP4
P2_RIGHT = K_KP6
P2_ATK = K_INSERT
P2_JMP = K_HOME
P2_BLK = K_PAGEUP

CONTROL_P1 = [P1_UP,P1_DOWN,P1_LEFT,P1_RIGHT,P1_ATK,P1_JMP,P1_BLK]
CONTROL_P2 = [P2_UP,P2_DOWN,P2_LEFT,P2_RIGHT,P2_ATK,P2_JMP,P2_BLK]

#Sleeps
COMBO_SLEEP = 200
CRITICAL_SLEEP = 1000
DAMAGED_SLEEP = 500
FALLING_SLEEP = 1000

class Event:
    """
    This is a superclass for any events that might be generated by an object
    and sent to the EventManager
    """
    def __init__(self):
        self.name = 'Generic Event'

class TickEvent(Event):
    def __init__(self):
        self.name = 'CPU Tick Event'

class QuitEvent(Event):
    def __init__(self):
        self.name = 'Program Quit Event'

class MapBuiltEvent(Event):
    def __init__(self, map):
        self.name = 'Map Finished Building Event'
        self.map = map

class GameStartedEvent(Event):
    def __init__(self, game):
        self.name = 'Game Started Event'
        self.game = game

class CharactorMoveRequest(Event):
    def __init__(self, direction):
        self.name = 'Charactor Move Request'
        self.direction = direction

class CharactorPlaceEvent(Event):
    """
    This event occurs when a Charactor is *placed* in a sector, ie it doesn't
    move there from an adjacent sector.
    """
    def __init__(self, charactor):
        self.name = 'Charactor Placement Event'
        self.charactor = charactor

class CharactorMoveEvent(Event):
    def __init__(self, charactor):
        self.name = 'Charactor Move Event'
        self.charactor = charactor

#From Rodrigo wrote all Events and Request

class CharactorAttackRequest(Event):
    def __init__(self, charactor):
        self.name = 'Charactor Attack Request'
        self.charactor = charactor

class CharactorAttackEvent(Event):
    def __init__(self,charactor):
        self.name = 'Charactor Attack Event'
        self.charactor = charactor

class CharactorJumpRequest(Event):
    def __init__(self, charactor):
        self.name = 'Charactor Jump Request'
        self.charactor = charactor

class CharactorJumpEvent(Event):
    def __init__(self,charactor):
        self.name = 'Charactor Jump Event'
        self.charactor = charactor

class CharactorStopJumpEvent(Event):
    def __init__(self, charactor):
        self.name = 'Charactor Stop Jump Event'
        self.charactor = charactor

class CharactorWalkEvent(Event):
    def __init__(self, direction, charactor):
        self.name = 'Charactor Walk Event Request'
        self.direction = direction
        self.charactor = charactor

class CharactorStopWalkEvent(Event):
    def __init__(self, direction, charactor):
        self.name = 'Charactor Stop Walk Request'
        self.direction = direction
        self.charactor = charactor

class CharactorRunEvent(Event):
    def __init__(self, charactor):
        self.name = 'Charactor Run Request'
        self.charactor = charactor

class CharactorStopRunEvent(Event):
    def __init__(self, charactor):
        self.name = 'Charactor Stop Run Request'
        self.charactor = charactor

class CharactorThroughRequest(Event):
    def __init__(self):
        self.name = 'Charactor Through Request'

class CharactorThroughEvent(Event):
    def __init__(self,charactor):
        self.name = 'Charactor Through Event'
        self.charactor = charactor

class CharactorPickItemRequest(Event):
    def __init__(self):
        self.name = 'Charactor Pick Item Request'

class CharactorPickItemEvent(Event):
    def __init__(self,charactor):
        self.name = 'Charactor Pick Item Event'
        self.charactor = charactor

class CharactorUseItemRequest(Event):
    def __init__(self):
        self.name = 'Charactor Use Item Request'

class CharactorUseItemEvent(Event):
    def __init__(self,charactor):
        self.name = 'Charactor Use Item Event'
        self.charactor = charactor

class CharactorDefendRequest(Event):
    def __init__(self, charactor):
        self.name = 'Charactor Defend Request'
	self.charactor = charactor

class CharactorDefendEvent(Event):
    def __init__(self,charactor):
        self.name = 'Charactor Defend Event'
        self.charactor = charactor

class CharactorGrabEvent(Event):
    def __init__(self,charactor):
        self.name = 'Charactor Through Event'
        self.charactor = charactor

class CharactorAdd2ComboRequest(Event):
    def __init__(self, key, charactor):
        self.name = 'Charactor Add2Combo Request'
        self.key = key
        self.charactor = charactor

class CharactorAdd2ComboEvent(Event):
    def __init__(self,charactor):
        self.name = 'Charactor Add2Combo Event'
        self.charactor = charactor

class CharactorStopAttack(Event):
    def __init__(self,charactor):
	self.name = 'Charactor Stop Attack Event'
	self.charactor = charactor
	
#------------------------------------------------------------------------------
class EventManager:
    """
    This object is responsible for coordinating most communication between the
    Model, View, and Controller.
    """
    def __init__(self):
        from weakref import WeakKeyDictionary
        self.listeners = WeakKeyDictionary()
        self.eventQueue = []

    #----------------------------------------------------------------------
    def RegisterListener(self, listener):
        self.listeners[listener] = 1

    #----------------------------------------------------------------------
    def UnregisterListener(self, listener):
        if listener in self.listeners.keys():
            del self.listeners[listener]
        
    #----------------------------------------------------------------------
    def Post(self, event):
        if not isinstance(event, TickEvent):
            Debug(event.name)
        for listener in self.listeners.keys():
            # NOTE: If the weakref has died, it will be automatically
            #       removed, so we do not need to worry about it.
            listener.Notify(event)

#------------------------------------------------------------------------------
#Wrote by Rodrigo
class KeyboardController:
    """..."""
    def __init__(self, evManager, game):
        self.evManager = evManager
        self.evManager.RegisterListener(self)
        self.game = game


    #----------------------------------------------------------------------
#From here I (Rodrigo) wrote all Key Requests
    def Notify(self, event):
        if isinstance(event, TickEvent):
            # Handle input events.
            for event in pygame.event.get():
                ev1 = None
                ev2 = None
                if event.type == QUIT:
                    ev1 = QuitEvent()
                elif event.type == KEYDOWN:
                    if event.key == K_ESCAPE:
                        ev1 = QuitEvent()
                    elif event.key == P1_UP:
                        ev2 = CharactorWalkEvent(DIRECTION_UP,self.game.players[0].charactor)
                        ev1 = CharactorAdd2ComboRequest(P1_UP,self.game.players[0].charactor)
                    elif event.key == P2_UP:
                        ev2 = CharactorWalkEvent(DIRECTION_UP,self.game.players[1].charactor)
                        ev1 = CharactorAdd2ComboRequest(P2_UP,self.game.players[1].charactor)
                    elif event.key == P1_DOWN:
                        ev2 = CharactorWalkEvent(DIRECTION_DOWN,self.game.players[0].charactor)
                        ev1 = CharactorAdd2ComboRequest(P1_DOWN,self.game.players[0].charactor)
                    elif event.key == P2_DOWN:
                        ev2 = CharactorWalkEvent(DIRECTION_DOWN,self.game.players[1].charactor)
                        ev1 = CharactorAdd2ComboRequest(P2_DOWN,self.game.players[1].charactor)
                    elif event.key == P1_LEFT:
                        ev2 = CharactorWalkEvent(DIRECTION_LEFT,self.game.players[0].charactor)
                        ev1 = CharactorAdd2ComboRequest(P1_LEFT,self.game.players[0].charactor)
                    elif event.key == P2_LEFT:
                        ev2 = CharactorWalkEvent(DIRECTION_LEFT,self.game.players[1].charactor)
                        ev1 = CharactorAdd2ComboRequest(P2_LEFT,self.game.players[1].charactor)
                    elif event.key == P1_RIGHT:
                        ev2 = CharactorWalkEvent(DIRECTION_RIGHT,self.game.players[0].charactor)
                        ev1 = CharactorAdd2ComboRequest(P1_RIGHT,self.game.players[0].charactor)
                    elif event.key == P2_RIGHT:
                        ev2 = CharactorWalkEvent(DIRECTION_RIGHT,self.game.players[1].charactor)
                        ev1 = CharactorAdd2ComboRequest(P2_RIGHT,self.game.players[1].charactor)
                    elif event.key == P1_ATK:
                        ev2 = CharactorAttackRequest(self.game.players[0].charactor)
                        ev1 = CharactorAdd2ComboRequest(P1_ATK,self.game.players[0].charactor)
                    elif event.key == P2_ATK:
                        ev2 = CharactorAttackRequest(self.game.players[1].charactor)
                        ev1 = CharactorAdd2ComboRequest(P2_ATK,self.game.players[1].charactor)
		    elif event.key == P1_BLK:
                        ev2 = CharactorDefendRequest(self.game.players[0].charactor)
                        ev1 = CharactorAdd2ComboRequest(P1_BLK,self.game.players[0].charactor)
		    elif event.key == P2_BLK:
                        ev2 = CharactorDefendRequest(self.game.players[1].charactor)
                        ev1 = CharactorAdd2ComboRequest(P2_BLK,self.game.players[1].charactor)
                    elif event.key == P1_JMP:
                        ev2 = CharactorJumpRequest(self.game.players[0].charactor)
                        ev1 = CharactorAdd2ComboRequest(P1_JMP,self.game.players[0].charactor)
                    elif event.key == P2_JMP:
                        ev2 = CharactorJumpRequest(self.game.players[1].charactor)
                        ev1 = CharactorAdd2ComboRequest(P2_JMP,self.game.players[1].charactor)
                        
                elif event.type == KEYUP:
                    if event.key == P1_UP:
                        ev1 = CharactorStopWalkEvent(DIRECTION_UP,self.game.players[0].charactor)
                    elif event.key == P2_UP:
                        ev1 = CharactorStopWalkEvent(DIRECTION_UP,self.game.players[1].charactor)
                    elif event.key == P1_DOWN:
                        ev1 = CharactorStopWalkEvent(DIRECTION_DOWN,self.game.players[0].charactor)
                    elif event.key == P2_DOWN:
                        ev1 = CharactorStopWalkEvent(DIRECTION_DOWN,self.game.players[1].charactor)
                    elif event.key == P1_LEFT:
                        ev1 = CharactorStopWalkEvent(DIRECTION_LEFT,self.game.players[0].charactor)
                    elif event.key == P2_LEFT:
                        ev1 = CharactorStopWalkEvent(DIRECTION_LEFT,self.game.players[1].charactor)
                    elif event.key == P1_RIGHT:
                        ev1 = CharactorStopWalkEvent(DIRECTION_RIGHT,self.game.players[0].charactor)
                    elif event.key == P2_RIGHT:
                        ev1 = CharactorStopWalkEvent(DIRECTION_RIGHT,self.game.players[1].charactor)
	#criado por loro
                    elif event.key == P1_ATK:
			ev1 = CharactorStopAttack(self.game.players[0].charactor)
		    elif event.key == P2_ATK:
			ev1 = CharactorStopAttack(self.game.players[1].charactor)

                if ev1:
                    self.evManager.Post(ev1)
                if ev2:
                    self.evManager.Post(ev2)

#------------------------------------------------------------------------------
class CPUSpinnerController:
    """..."""
    def __init__(self, evManager):
        self.evManager = evManager
        self.evManager.RegisterListener(self)

        self.keepGoing = 1

    #----------------------------------------------------------------------
    def Run(self):
        while self.keepGoing:
            event = TickEvent()
            self.evManager.Post(event)

    #----------------------------------------------------------------------
    def Notify(self, event):
        if isinstance(event, QuitEvent):
            # This will stop the while loop from running.
            self.keepGoing = 0


import pygame
from pygame.locals import *

#------------------------------------------------------------------------------
"""
class SectorSprite(pygame.sprite.Sprite):
    def __init__(self, sector, group=None):
        pygame.sprite.Sprite.__init__(self, group)
        self.image = pygame.Surface((132, 132))
        self.image.fill((0, 255, 128))

        self.sector = sector
"""
#------------------------------------------------------------------------------
#Wrote by Rodrigo

# Lôro, tem que fazer com q o jogo instacie pelo menos dois personagens diferentes (com imagens diferentes)

class CharactorSprite(pygame.sprite.Sprite):
    def __init__(self, group=None):
        pygame.sprite.Sprite.__init__(self, group)
        
        self.image = pygame.image.load("xiao.png")
        self.rect  = self.image.get_rect()

        self.moveTo = None
	self.image_sleep = 40
	self.flag_switch = 0
	self.flag_atk = 0
	self.old_sprite = pygame.image.load("xiao.png")
    #----------------------------------------------------------------------
    def update(self):
        if self.moveTo:
            self.rect.center = self.moveTo
            self.moveTo = None

#------------------------------------------------------------------------------
class PygameView:
    """..."""
    def __init__(self, evManager):
        self.evManager = evManager
        self.evManager.RegisterListener(self)

        pygame.init()
        self.window = pygame.display.set_mode((WIDTH, HEIGHT))
        pygame.display.set_caption('Xiao Fighter')
        self.background = pygame.Surface(self.window.get_size())
        self.background.fill((255, 255, 255))

        self.backSprites = pygame.sprite.RenderUpdates()
        self.frontSprites = pygame.sprite.RenderUpdates()

        self.window.blit(self.background, (0,0))
        pygame.display.flip()

    #----------------------------------------------------------------------
#Wrote by Rodrigo    
    def ShowCharactor(self, charactor):
        charactorSprite = CharactorSprite(self.frontSprites)
#        sector = charactor.sector
#        sectorSprite = self.GetSectorSprite(sector)
        charactor.sprite = charactorSprite
        charactorSprite.rect.center = charactor.rect.center

    #----------------------------------------------------------------------
#Wrote by Rodrigo
    def MoveCharactor(self, charactor):
        charactor.sprite.moveTo = charactor.rect.center
	charactorSprite = charactor.sprite
	if charactorSprite.flag_switch == 0:
		charactorSprite.image_sleep -= 1
	else:
		charactorSprite.image_sleep += 1
	if charactor.eyeDirection == 3:
		if charactorSprite.image_sleep== 0:
			charactorSprite.image = pygame.image.load("xiao2.png")
			charactorSprite.flag_switch = 1
		if charactorSprite.image_sleep== 40:
			charactorSprite.image = pygame.image.load("xiao.png")
			charactorSprite.flag_switch = 0
		if charactorSprite.image_sleep == 20:
			charactorSprite.image = pygame.image.load("xiao3.png")
	else:
		if charactorSprite.image_sleep== 0:
			charactorSprite.image = pygame.image.load("xiao2.png")
			charactorSprite.image = pygame.transform.flip(charactorSprite.image,1,0)
			charactorSprite.flag_switch = 1
		if charactorSprite.image_sleep== 40:
			charactorSprite.image = pygame.image.load("xiao.png")
			charactorSprite.image = pygame.transform.flip(charactorSprite.image,1,0)
			charactorSprite.flag_switch = 0
		if charactorSprite.image_sleep == 20:
			charactorSprite.image = pygame.image.load("xiao3.png")
			charactorSprite.image = pygame.transform.flip(charactorSprite.image,1,0)

    #----------------------------------------------------------------------
    def Notify(self, event):
        if isinstance(event, TickEvent):
            #Draw Everything
            self.backSprites.clear( self.window, self.background)
            self.frontSprites.clear( self.window, self.background)

            self.backSprites.update()
            self.frontSprites.update()

            dirtyRects1 = self.backSprites.draw(self.window)
            dirtyRects2 = self.frontSprites.draw(self.window)
            
            dirtyRects = dirtyRects1 + dirtyRects2
            pygame.display.update(dirtyRects)


        elif isinstance(event, MapBuiltEvent):
            map = event.map
            self.ShowMap(map)

        elif isinstance(event, CharactorPlaceEvent):
            self.ShowCharactor(event.charactor)

        elif isinstance(event, CharactorMoveEvent):
            self.MoveCharactor(event.charactor)


#------------------------------------------------------------------------------
class Game:
    """..."""

    STATE_PREPARING = 0
    STATE_RUNNING = 1
    STATE_PAUSED = 2

    #----------------------------------------------------------------------
    def __init__(self, evManager):
        self.evManager = evManager
        self.evManager.RegisterListener(self)

        self.state = Game.STATE_PREPARING
        
        self.players = [Player(evManager,CONTROL_P1,START_RECT1),Player(evManager,CONTROL_P2,START_RECT2)]
#        self.map = Map(evManager)

    #----------------------------------------------------------------------
    def Start(self):
#        self.map.Build()
        self.state = Game.STATE_RUNNING
        ev = GameStartedEvent(self)
        self.evManager.Post(ev)

    #----------------------------------------------------------------------
    def Notify(self, event):
        if isinstance(event, TickEvent):
            if self.state == Game.STATE_PREPARING:
                self.Start()

#------------------------------------------------------------------------------
class Player:
    """..."""
    def __init__(self, evManager, controls, start_rect):
        self.evManager = evManager
        #self.evManager.RegisterListener(self)

        self.charactor = Charactor(evManager,controls,start_rect)

#------------------------------------------------------------------------------
class Charactor:
    """..."""
    def __init__(self, evManager, controls, start_rect):
        self.evManager = evManager
        self.evManager.RegisterListener(self)
        self.controls = controls
        self.combo = [-1,-1,-1]
        self.combo_sleep = -1
        self.hp = 500
        self.mp = 100
        self.speed = -1
        self.status = ""
        self.eyeDirection = DIRECTION_RIGHT
        self.up = False
        self.up_sleep = -1
        self.down = False
        self.down_sleep = -1
        self.left = False
        self.right = False
        self.jump_times = -1
        self.jump_dir = 0
        self.jump_sleep = -1
        self.jump_sleeph = -1
        self.jump_directions = [False,False,False,False]
	self.block_sleep = -1
	self.critical_sleep = -1
	self.damarea = pygame.Rect(0,0,0,0)
	self.damage_sim = 10
	self.damage_critical = 20
	self.falling_direction = -1
        self.start_rect = start_rect
        self.sprite = None
    #----------------------------------------------------------------------
#Wrote by Rodrigo
    def Move(self,direction):
        if direction == DIRECTION_UP and self.rect.top-1>=TOP_LIMIT:
            self.rect = self.rect.move([0,-1])
            ev = CharactorMoveEvent(self)
            self.evManager.Post(ev)
        elif direction == DIRECTION_DOWN and self.rect.bottom+1<=600:
            self.rect = self.rect.move([0,1])
            ev = CharactorMoveEvent(self)
            self.evManager.Post(ev)
        elif direction == DIRECTION_LEFT and self.rect.left-1>=0:
            self.rect = self.rect.move([-1,0])
            self.eyeDirection = DIRECTION_LEFT
            ev = CharactorMoveEvent(self)
            self.evManager.Post(ev)
        elif direction == DIRECTION_RIGHT and self.rect.right+1<=800:
            self.rect = self.rect.move([1,0])
            self.eyeDirection = DIRECTION_RIGHT
            ev = CharactorMoveEvent(self)
            self.evManager.Post(ev)
    #----------------------------------------------------------------------
#Wrote by Rodrigo
    def Walk(self, direction):
        if not self.status == "jumping" and not self.status == "dead" and not self.status == "damaged" and not self.status == "standby":
            if not self.status == "running":
                self.speed = 0
                self.status = "walking"
            
            if direction == DIRECTION_UP:
                self.up = True
                self.up_sleep = 0
            elif direction == DIRECTION_DOWN:
                self.down = True
                self.down_sleep = 0
            elif direction == DIRECTION_LEFT:
                self.left = True
            elif direction == DIRECTION_RIGHT:
                self.right = True
    #----------------------------------------------------------------------
#Wrote by Rodrigo
    def Walking(self):
        if self.speed == 0:
            self.speed = WALK_SPEED
            if self.up:
                if self.up_sleep == 0:
                    self.up_sleep = VERT_SPEED
                    self.Move(DIRECTION_UP)
                elif self.up_sleep > 0:
                    self.up_sleep -= 1
            if self.down:
                if self.down_sleep == 0:
                    self.down_sleep = VERT_SPEED
                    self.Move(DIRECTION_DOWN)
                elif self.down_sleep > 0:
                    self.down_sleep -= 1
            if self.left:
                self.Move(DIRECTION_LEFT)
            if self.right:
                self.Move(DIRECTION_RIGHT)
        elif self.speed > 0:
            self.speed -= 1

    #----------------------------------------------------------------------
#Wrote by Rodrigo
    def StopWalk(self, direction):
        if direction == DIRECTION_UP:
            self.up = False
            self.up_sleep = -1
        elif direction == DIRECTION_DOWN:
            self.down = False
            self.down_sleep = -1
        elif direction == DIRECTION_LEFT:
            self.left = False
        elif direction == DIRECTION_RIGHT:
            self.right = False

        if self.status == "walking" and not self.up and not self.down and not self.left and not self.right:
                self.speed = -1
                self.status = ""
    #----------------------------------------------------------------------
#Wrote by Rodrigo

#Lôro, Criar frames diferenstes para a corrida.

    def Run(self):
        if not self.status == "jumping" and not self.status == "dead" and not self.status == "damaged" and not self.status == "standby":
            self.speed = 0
            self.status = "running"
    #----------------------------------------------------------------------
#Wrote by Rodrigo
    def Running(self):
        if self.speed == 0:
            self.speed = RUN_SPEED
            self.Move(self.eyeDirection)
            if self.up:
                if self.up_sleep == 0:
                    self.up_sleep = VERT_SPEED
                    self.Move(DIRECTION_UP)
                elif self.up_sleep > 0:
                    self.up_sleep -= 1
            if self.down:
                if self.down_sleep == 0:
                    self.down_sleep = VERT_SPEED
                    self.Move(DIRECTION_DOWN)
                elif self.down_sleep > 0:
                    self.down_sleep -= 1
        else:
            self.speed -= 1

    #----------------------------------------------------------------------
#Wrote by Rodrigo
    def StopRun(self):
         self.speed = -1
         self.status = ""
    #----------------------------------------------------------------------

#Wrote by Rodrigo

#Lôro, criar frames diferentes para o pulo

    def Jump(self):
        if self.status == "walking":
            self.jump_directions[2] = True
            self.jump_sleeph = WALK_SPEED
        elif self.status == "running":
            self.jump_directions[3] = True
            self.jump_sleeph = RUN_SPEED

        if not self.status == "jumping" and not self.status == "damaged" and not self.status == "standby":
            self.status = "jumping"
            if(self.combo[0]!=-1):                 
                if self.combo[0] == self.controls[0]:
                    self.jump_directions[0] = True
                elif self.combo[0] == self.controls[1]:
                    self.jump_directions[1] = True
            elif self.combo[1]!=-1:                 
                if self.combo[1] == self.controls[0]:
                    self.jump_directions[0] = True
                elif self.combo[1] == self.controls[1]:
                    self.jump_directions[1] = True
            if self.jump_directions[0] == self.jump_directions[1] == True:
                self.jump_directions[0] = self.jump_directions[1] = False

            self.jump_times = 1
            self.jump_dir = 1
            self.jump_sleep = 0
    #----------------------------------------------------------------------
#Wrote by Rodrigo
    def JumpWalking(self):
        if self.jump_sleeph == 0:
            self.jump_sleeph = WALK_SPEED
            if self.eyeDirection == DIRECTION_LEFT:
                self.Move(DIRECTION_LEFT)
            else:
                self.Move(DIRECTION_RIGHT)
        elif self.jump_sleeph > 0:
            self.jump_sleeph -= 1
    #----------------------------------------------------------------------
#Wrote by Rodrigo

#Lôro, criar frames diferentes para o pulo com corrida

    def JumpRunning(self):
        if self.jump_sleeph == 0:
            self.jump_sleeph = RUN_SPEED
            if self.eyeDirection == DIRECTION_LEFT:
                self.Move(DIRECTION_LEFT)
                self.Move(DIRECTION_LEFT)
            else:
                self.Move(DIRECTION_RIGHT)
                self.Move(DIRECTION_RIGHT)
        elif self.jump_sleeph > 0:
            self.jump_sleeph -= 1
            

    #----------------------------------------------------------------------
#Wrote by Rodrigo
    def SleepCalc(self,min,max):
        if self.jump_times-min <= (max-min)*1/10:
            return 1
        elif self.jump_times-min <= (max-min)*3/10:
            return 2
        elif self.jump_times-min <= (max-min)*6/10:
            return 3
        elif self.jump_times-min <= (max-min)*10/10:
            return 5
    #----------------------------------------------------------------------
#Wrote by Rodrigo
    def JumpGoingUp(self):
        if self.jump_directions[2]:
            self.JumpWalking()  
        elif self.jump_directions[3]:
            self. JumpRunning()

        if self.jump_times == MAX_JUMPS:
            self.jump_dir = 0

        if self.jump_sleep == 0:                
            self.Move(DIRECTION_UP)
            self.jump_sleep = self.SleepCalc(0,MAX_JUMPS)
            self.jump_times += 1;

        elif self.jump_sleep > 0:
            self.jump_sleep -= 1

    #----------------------------------------------------------------------
#Wrote by Rodrigo
    def JumpMaxStay(self):
        print "MAX!!"
        MAX_STAY = -1
        if self.status == "running":
            MAX_STAY = MAX_STAY_RUN
        elif self.status == "walking":
            MAX_STAY = MAX_STAY_WALK

        if self.jump_times <= MAX_JUMPS + MAX_STAY:
                self.jump_times += 1
                if self.jump_directions[2]:
                    self.JumpWalking()  
                elif self.jump_directions[3]:
                    self. JumpRunning()
        else :
            self.jump_times = MAX_JUMPS
            self.jump_dir = -1


    #----------------------------------------------------------------------
#Wrote by Rodrigo
    def JumpGoingDown(self):
        if self.jump_times == MAX_JUMPS:
            self.jump_times -= 1
        
        if self.jump_directions[2]:
            self.JumpWalking()  
        elif self.jump_directions[3]:
            self. JumpRunning()

        if self.jump_sleep == 0:                
            self.Move(DIRECTION_DOWN)
            self.jump_sleep = self.SleepCalc(0,MAX_JUMPS)
            self.jump_times -=1;
            
        elif self.jump_sleep > 0:
            self.jump_sleep -= 1

    #----------------------------------------------------------------------
#Wrote by Rodrigo
    def Jumping(self):
        ev = None
        if self.jump_dir == 1:
            self.JumpGoingUp()

        elif self.jump_dir == 0:
            self.JumpMaxStay()

        elif self.jump_dir == -1 and not self.jump_times == 0:
            self.JumpGoingDown()

        #End of the Jump
        elif self.jump_times == 0:
            ev = CharactorStopJumpEvent(self)
            self.evManager.Post(ev)

    #----------------------------------------------------------------------
#Wrote by Rodrigo
    def StopJump(self):
       self.jump_directions = [False,False,False,False]
       if self.up or self.down or self.left or self.right:
           self.status = "walking"
       else:
           self.status = ""
    #----------------------------------------------------------------------
#Wrote by Dedeu

#Lôro, criar frames para o ataque

    def Attack(self,charactor):
	charactor.sprite.old_sprite = charactor.sprite.image
        if not self.status == "jumping" and not self.status == "attacking" and not self.status == "dead" and not self.status == "standby" and not self.status == "walking" and not self.status == "damaged":
	    if self.eyeDirection == DIRECTION_RIGHT:
		ret = pygame.Rect(self.rect.right, self.rect.top+XIAO_HEIGHT/2, 5, 1)
		charactor.sprite.image = pygame.image.load("xiao_atk.png") 
		
	    else:
		ret = pygame.Rect(self.rect.left, self.rect.top+XIAO_HEIGHT/2, 5, 1) 
		charactor.sprite.image = pygame.transform.flip(pygame.image.load("xiao_atk.png"),1,0)

	    self.damarea = ret
	    self.status = "attacking"
	    self.combo_hit = 1
	    self.att_sleep = 3000
	    ev = CharactorAttackEvent(self)
	    self.evManager.Post(ev)
	elif self.status == "attacking":
	     if   self.combo_hit < 3:
		  self.combo_hit += 1
	     elif self.combo_hit == 3:
		  self.critical_sleep = CRITICAL_SLEEP
		  self.combo_hit = 1
		  self.status = "standby"
	     ev = CharactorAttackEvent(self)
	     self.evManager.Post(ev)
    #------------------------------------------------------------------------
    def StopAttack(self,charactor):
	charactor.sprite.image = charactor.sprite.old_sprite
 
 
    #------------------------------------------------------------------------
#Lôro, criar frames para o dano (note que q deve ter um para o dano normal e outro para o dano crítico, incluindo a queda)

    def Damaged (self, charactor):
	if self != charactor and self.rect.colliderect(charactor.damarea) and not self.status == "blocking":
	    if charactor.combo_hit != 3:
		self.hp -= charactor.damage_sim
		self.status = "damaged"
		self.dam_sleep = DAMAGED_SLEEP
	    else:
		self.hp -= charactor.damage_critical
		self.status = "falling"
		self.falling_direction = charactor.eyeDirection
		self.dam_sleep = FALLING_SLEEP
	    print(self.hp)
	elif self.status == "blocking":
	    if charactor.combo_hit == 3:
		self.status = ""
	    print(self.hp)

    #------------------------------------------------------------------------

#Lôro, criar frames para a defesa

    def Defend (self):
	if not self.status == "damaged" and not self.status == "jumping" and not self.status == "blocking" and not self.status == "dead" and not self.status == "standby":
	    self.status = "blocking"
	    self.block_sleep = 10000   
    #----------------------------------------------------------------------
#Wrote by Rodrigo
    def Place(self):
        self.rect = self.start_rect
        ev = CharactorPlaceEvent(self)
        self.evManager.Post(ev)
    #----------------------------------------------------------------------
#Wrote by Rodrigo    
    def Add2Combo(self, key):
        self.combo_sleep = COMBO_SLEEP        
        if(len(self.combo)<3):
            self.combo.append(key)
        else:
            self.combo.pop(0)
            self.combo.append(key)
        ev = CharactorAdd2ComboEvent(self)
        self.evManager.Post(ev)
    #----------------------------------------------------------------------
#Wrote by Rodrigo    
    def VerifyCombo(self):
        combo_atual = -1
        if self.combo[2] == self.controls[2]:
            combo_atual = DIRECTION_LEFT
        elif self.combo[2] == self.controls[3]:
            combo_atual = DIRECTION_RIGHT

        if self.combo[1] == self.controls[3] and self.combo[2] == self.controls[3] and not self.status == "running":
            combo_atual = DIRECTION_RIGHT
            ev = CharactorRunEvent(self)
            self.evManager.Post(ev)
        elif self.combo[1] == self.controls[2] and self.combo[2] == self.controls[2] and not self.status == "running":
            combo_atual = DIRECTION_LEFT
            ev = CharactorRunEvent(self)
            self.evManager.Post(ev)
        elif self.status == "running" and self.combo[2] != self.controls[0] and self.combo[2] != self.controls[1]:
            if (self.eyeDirection == DIRECTION_LEFT and combo_atual == DIRECTION_RIGHT) or (self.eyeDirection == DIRECTION_RIGHT and combo_atual == DIRECTION_LEFT):
                ev = CharactorStopRunEvent(self)
                self.evManager.Post(ev)


    #----------------------------------------------------------------------
#Wrote by Rodrigo    
    def CleanCombo(self):
        self.combo_sleep = -1
        self.combo = [-1,-1,-1]
	
    #----------------------------------------------------------------------
#Wrote by Rodrigo    
    def Notify(self, event):
        if isinstance(event, GameStartedEvent):
#            map = event.game.map
            self.Place()

        elif isinstance(event, CharactorMoveRequest):
            self.Move(event.direction)

        elif isinstance(event, CharactorWalkEvent) and event.charactor == self:
            self.Walk(event.direction)

        elif isinstance(event, CharactorStopWalkEvent) and event.charactor == self:
            self.StopWalk(event.direction)

        elif isinstance(event, CharactorRunEvent) and event.charactor == self:
            self.Run()

        elif isinstance(event, CharactorStopRunEvent) and event.charactor == self:
            self.StopRun()

        elif isinstance(event, CharactorJumpRequest) and event.charactor == self:
            self.Jump()

        elif isinstance(event, CharactorStopJumpEvent) and event.charactor == self:
            self.StopJump()
      
	elif isinstance(event, CharactorAttackRequest) and event.charactor == self:
	    self.Attack(event.charactor)

	elif isinstance(event, CharactorDefendRequest) and event.charactor == self:
	    self.Defend()
	
	elif isinstance(event, CharactorAttackEvent):
	    self.Damaged(event.charactor)
  
        elif isinstance(event, CharactorAdd2ComboRequest) and event.charactor == self:
            self.Add2Combo(event.key)

        elif isinstance(event, CharactorAdd2ComboEvent)and event.charactor == self:
            self.VerifyCombo()
	
	elif isinstance(event, CharactorStopAttack) and event.charactor == self:
	    self.StopAttack(event.charactor)

        elif isinstance(event, TickEvent):
	    
            if self.hp <= 0:
		self.status == "dead"
	    elif self.status == "jumping":
		self.Jumping()   
            elif self.status == "running":
                self.Running()
            elif self.status == "walking":
                self.Walking()
	    elif self.status == "blocking":
		if self.block_sleep == 0:
		    self.status = ""
		else:
		    self.block_sleep -= 1
	    elif self.status == "standby":
		if self.critical_sleep == 0:
		    self.status = ""
		else:
		   self.critical_sleep -= 1
	    elif self.status == "attacking":
		if self.att_sleep == 0:
		   self.status = ""
		   self.damarea = pygame.Rect(0,0,0,0)
		   self.combo_hit = 0
		else:
		   self.att_sleep -= 1
		   self.critical_sleep -= 1

	    elif self.status == "falling":
		if self.dam_sleep == 0:
		    self.status = ""
		    self.falling_direction = -1
		elif self.dam_sleep > 0:
		    if self.dam_sleep%RUN_SPEED == 0 and self.dam_sleep >= 490:      
			print "AAAH!"
			self.Move(self.falling_direction)
		    self.dam_sleep -= 1		    
	
	    elif self.status == "damaged":
		if self.dam_sleep == 0:
		    self.status = ""
		    self.falling_direction = -1
		else:
		    self.dam_sleep -= 1

            if self.combo_sleep==0:
                self.CleanCombo()
            elif self.combo_sleep>0:
                self.combo_sleep -= 1
              

#Lôro, gerar o mapa da fase. ja definimos a posição maxima q um personagem pode atingir, use-a como parametro

#------------------------------------------------------------------------------
"""
class Map:
    def __init__(self, evManager):
        self.evManager = evManager
        #self.evManager.RegisterListener(self)

        self.sectors = range(9)
        self.startSectorIndex = 0
"""
    #----------------------------------------------------------------------
""" 
    def Build(self):
        for i in range(9):
            self.sectors[i] = Sector(self.evManager)

        self.sectors[3].neighbors[DIRECTION_UP] = self.sectors[0]
        self.sectors[4].neighbors[DIRECTION_UP] = self.sectors[1]
        self.sectors[5].neighbors[DIRECTION_UP] = self.sectors[2]
        self.sectors[6].neighbors[DIRECTION_UP] = self.sectors[3]
        self.sectors[7].neighbors[DIRECTION_UP] = self.sectors[4]
        self.sectors[8].neighbors[DIRECTION_UP] = self.sectors[5]

        self.sectors[0].neighbors[DIRECTION_DOWN] = self.sectors[3]
        self.sectors[1].neighbors[DIRECTION_DOWN] = self.sectors[4]
        self.sectors[2].neighbors[DIRECTION_DOWN] = self.sectors[5]
        self.sectors[3].neighbors[DIRECTION_DOWN] = self.sectors[6]
        self.sectors[4].neighbors[DIRECTION_DOWN] = self.sectors[7]
        self.sectors[5].neighbors[DIRECTION_DOWN] = self.sectors[8]

        self.sectors[1].neighbors[DIRECTION_LEFT] = self.sectors[0]
        self.sectors[2].neighbors[DIRECTION_LEFT] = self.sectors[1]
        self.sectors[4].neighbors[DIRECTION_LEFT] = self.sectors[3]
        self.sectors[5].neighbors[DIRECTION_LEFT] = self.sectors[4]
        self.sectors[7].neighbors[DIRECTION_LEFT] = self.sectors[6]
        self.sectors[8].neighbors[DIRECTION_LEFT] = self.sectors[7]

        self.sectors[0].neighbors[DIRECTION_RIGHT] = self.sectors[1]
        self.sectors[1].neighbors[DIRECTION_RIGHT] = self.sectors[2]
        self.sectors[3].neighbors[DIRECTION_RIGHT] = self.sectors[4]
        self.sectors[4].neighbors[DIRECTION_RIGHT] = self.sectors[5]
        self.sectors[6].neighbors[DIRECTION_RIGHT] = self.sectors[7]
        self.sectors[7].neighbors[DIRECTION_RIGHT] = self.sectors[8]

        ev = MapBuiltEvent(self)
        self.evManager.Post(ev)
"""
#------------------------------------------------------------------------------
"""
class Sector:
    def __init__(self, evManager):
        self.evManager = evManager
        #self.evManager.RegisterListener(self)

        self.neighbors = range(4)

        self.neighbors[DIRECTION_UP] = None
        self.neighbors[DIRECTION_DOWN] = None
        self.neighbors[DIRECTION_LEFT] = None
        self.neighbors[DIRECTION_RIGHT] = None

    #----------------------------------------------------------------------
    def MovePossible(self, direction):
        if self.neighbors[direction]:
            return 1

"""
#------------------------------------------------------------------------------
def main():
    """..."""
    evManager = EventManager()

    spinner = CPUSpinnerController(evManager)
    pygameView = PygameView(evManager)
    game = Game(evManager)
    keybd = KeyboardController(evManager, game)
    
    spinner.Run()

if __name__ == '__main__':
    main()
